package com.xbongbong.paas.controller.mobile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.pojo.dto.ApprovalRecordsDTO;
import com.xbongbong.paas.pojo.dto.FormDataGetDTO;
import com.xbongbong.paas.pojo.vo.ApprovalRecordsVO;
import com.xbongbong.paas.pojo.vo.FormDataAddGetVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateGetVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.applist.pojo.vo.ListPurchasedVO;
import com.xbongbong.pro.businesstage.pojo.vo.ChangeClueStatusVO;
import com.xbongbong.pro.clue.pojo.dto.ChangeClueStatusDTO;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.detailtab.dto.ChangeDocumentStatusSaveDTO;
import com.xbongbong.pro.detailtab.dto.ClueConvertSaveDTO;
import com.xbongbong.pro.detailtab.dto.ClueConvertSaveVO;
import com.xbongbong.pro.detailtab.dto.DetailClueConvertDTO;
import com.xbongbong.pro.detailtab.dto.DetailCommunicateDTO;
import com.xbongbong.pro.detailtab.dto.DetailCopyDTO;
import com.xbongbong.pro.detailtab.dto.DetailTabDataGetDTO;
import com.xbongbong.pro.detailtab.dto.DistributionPerformanceSaveDTO;
import com.xbongbong.pro.detailtab.dto.LinkAddBeforeDTO;
import com.xbongbong.pro.detailtab.dto.LinkAddGetDTO;
import com.xbongbong.pro.detailtab.dto.OrderOnPinDTO;
import com.xbongbong.pro.detailtab.dto.SetDefaultBomVersionDTO;
import com.xbongbong.pro.detailtab.dto.SupplierProductAddDTO;
import com.xbongbong.pro.detailtab.dto.SupplierProductDelDTO;
import com.xbongbong.pro.detailtab.vo.ChangeDocumentStatusSaveVO;
import com.xbongbong.pro.detailtab.vo.DetailCommunicateVO;
import com.xbongbong.pro.detailtab.vo.DetailTabGetVO;
import com.xbongbong.pro.detailtab.vo.DetailTabLinkAddBeforeVO;
import com.xbongbong.pro.detailtab.vo.DistributionPerformanceGetVO;
import com.xbongbong.pro.detailtab.vo.HistoryStageVO;
import com.xbongbong.pro.detailtab.vo.InvoiceExpressGetVO;
import com.xbongbong.pro.detailtab.vo.ProductDetailVO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.detailtab.vo.SupplierProductVO;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.fromdatadictionary.pojo.vo.DictionaryArrayVO;
import com.xbongbong.pro.outstock.pojo.dto.OutstockShippingDTO;
import com.xbongbong.pro.outstock.pojo.vo.OutstockShippingVO;
import com.xbongbong.pro.payment.pojo.vo.PaymentVO;
import com.xbongbong.pro.payplan.pojo.dto.PayPlanBadReturnDTO;
import com.xbongbong.pro.payplan.pojo.vo.PayPlanVO;
import com.xbongbong.pro.product.pojo.vo.RelationProductListVO;
import com.xbongbong.pro.quatation.pojo.dto.QuotationHistoryDTO;
import com.xbongbong.pro.webdetail.pojo.dto.PaymentReturnDTO;
import com.xbongbong.pro.weblist.pojo.dto.SaasBaseDTO;
import com.xbongbong.pro.weblist.pojo.vo.WaitPurchaseProductVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.service.BusinessProductService;
import com.xbongbong.saas.service.ClueService;
import com.xbongbong.saas.service.PayPlanService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.service.QuotationService;
import com.xbongbong.saas.service.SaasDetailTabService;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Objects;

/**
 * 移动端详情页tab栏接口
 *
 * @author long.rao
 * @version v1.0
 * @date 2019/4/4 13:52
 * @since v1.0
 */
@RestController
@RequestMapping(value = XbbProConstant.API_ROOT_PREFIX + "/mobile/detail/tab")
public class MobileSaasDetailTabController {

    @Resource
    private SaasDetailTabService saasDetailTabService;
    @Resource
    private BusinessProductService businessProductService;
    @Resource
    private PaymentService paymentService;
    @Resource
    private QuotationService quotationService;
    @Resource
    private PayPlanService payPlanService;
    @Resource
    private ClueService clueService;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    /**
     * 回款坏账还原
     * @param paymentReturnDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/badDebtReturn", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String badDebtReturn(@RequestBody @Valid PaymentReturnDTO paymentReturnDTO, BindingResult br) {
        XbbResponse<PaymentVO> response;
        if(br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                PaymentVO paymentVO = paymentService.badDebtReturn(paymentReturnDTO);
                response = new XbbResponse<>(paymentVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/payPlan/badDebtReturn", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String payPlanBadDebtReturn(@RequestBody @Valid PayPlanBadReturnDTO payPlanBadReturnDTO, BindingResult br) {
        XbbResponse<PayPlanVO> response;
        if(br.hasErrors()){
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                PayPlanVO payPlanVO = payPlanService.badDebtReturn(payPlanBadReturnDTO);
                response = new XbbResponse<>(payPlanVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 阶段记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-04 13:59
     */
    @RequestMapping(value = "/getBusinessHistoryStage", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBusinessHistoryStage(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<HistoryStageVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                HistoryStageVO historyStageVO = saasDetailTabService.getHistoryStage(detailTabDataGetDTO);
                response = new XbbResponse<>(historyStageVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 应收款
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-04 14:04
     *
     * @version2 这时候的应收款已经是应收款了 2020/9/1
     */
    @RequestMapping(value = "/payment/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPayment(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(), 0L, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPayment(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/distributionPerformance/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getDistributionPerformance(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DistributionPerformanceGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DistributionPerformanceGetVO distributionPerformanceGetVO = saasDetailTabService.getDistributionPerformance(detailTabDataGetDTO);
                response = new XbbResponse<>(distributionPerformanceGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/distributionPerformance/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveDistributionPerformance(@RequestBody @Valid DistributionPerformanceSaveDTO distributionPerformanceSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                // ----------------------------------repeat post----------------------------------------------
                // 判断是否跳过重复提交校验
                if (!Boolean.TRUE.equals(distributionPerformanceSaveDTO.getIgnoreConCheck())) {
                    //重复提交校验
                    if (!paasRedisHelper.checkConcurrentLock(distributionPerformanceSaveDTO)) {
                        response = new XbbResponse<>(new XbbException(SystemErrorCodeEnum.API_ERROR_100003));
                        return JSON.toJSONString(response);
                    }
                }
                // ----------------------------------repeat post----------------------------------------------

                BaseVO baseVO = saasDetailTabService.saveDistributionPerformance(distributionPerformanceSaveDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取BOM结构
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-09 09:36
     * @version v1.0
     * @since v1.0
     */
    @RequestMapping(value = "/bomBill/getBomBillProductStructure", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBomBillProductStructure(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getBomProductStructure(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 详情页获取关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-09 10:15
     * @version v1.0
     * @since v1.0
     */
//    @RequestMapping(value = "/productList/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
//    public String getProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
//        XbbResponse<BusinessProductListVO> response;
//        if (br.hasErrors()) {
//            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
//            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
//        } else {
//            try {
//                BusinessProductListVO businessProductListVO = businessProductService.getBusinessProductList(detailTabDataGetDTO);
//                response = new XbbResponse<>(businessProductListVO);
//            } catch (XbbException e) {
//                response = new XbbResponse<>(e);
//            }
//        }
//        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
//    }

    /**
     * 付款计划
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-08 21:14
     */
    @RequestMapping(value = "/payPlan/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPayPlan(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPayPlan(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 应收款详情页回款单
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-09 15:10
     */
    @RequestMapping(value = "/paymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaymentSheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //这边记住需要用回款单的businessType,因为下面取的都是回款单列表
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.PAYMENT_SHEET.getCode(), BasicConstant.ZERO_LONG, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaymentSheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 回款单详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @date 19/11/29 029 22:04
     * @update 19/11/29 029 22:04
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/redPaymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedPaymentSheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedPaymentSheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 应收款详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/redReceivables/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedReceivables(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedReceivables(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 付款单详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/redPaySheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedPaySheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedPaySheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 付款单记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-09 19:04
     */
    @RequestMapping(value = "/paySheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaySheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                //这边记住需要用付款单的businessType,因为下面取的都是付款单列表
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.PAY_SHEET.getCode(), BasicConstant.ZERO_LONG, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaySheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 开票历史
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-09 20:51
     */
    @RequestMapping(value = "/invoiceHistory/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInvoiceHistory(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getInvoiceHistory(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取进项发票开票历史
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/purchaseInvoiceHistory/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchaseInvoiceHistory(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPurchaseInvoiceHistory(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 其他收入单详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/redOtherIncome/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedOtherIncome(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedOtherIncome(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 其他支出单详情-红冲记录
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/redOtherExpense/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedOtherExpense(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedOtherExpense(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 发票寄送信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-10 19:36
     */
    @RequestMapping(value = "/customerInvoiceExpress/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInvoiceAndExpress(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<InvoiceExpressGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                InvoiceExpressGetVO invoiceExpressGetVO = saasDetailTabService.getCustomerInvoiceExpress(detailTabDataGetDTO);
                response = new XbbResponse<>(invoiceExpressGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取产品详情
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author youli.chen
     * @date 13:53 2019/4/9
     * @since v1.0
     **/
    @RequestMapping(value = "/product/detail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String productDetail(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductDetailVO productDetailVO = saasDetailTabService.productDetail(detailTabDataGetDTO);
                response = new XbbResponse<>(productDetailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取父产品下的子产品列表
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author youli.chen
     * @date 13:53 2019/4/9
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getChildProductList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChildProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getChildProductListAndSpec(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取单据关联入库记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author youli.chen
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/instock/relationalList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String relationalInstockList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.relationalInstockList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取产品供应商列表
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author youli.chen
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getSupplier", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getSupplier(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.SUPPLIER.getCode(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getSupplierList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取单据关联出库记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author youli.chen
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/outstock/relationalList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String relationalOutstockList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.relationalOutstockList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取供应商关联的采购合同
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author youli.chen
     * @date 9:58 2019/3/27
     * @since v1.0
     **/
    @RequestMapping(value = "/supplier/purchaseList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String supplierPurchaseList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.supplierPurchaseList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品详情页子产品库存信息
     *
     * @param detailTabDataGetDTO 入参
     * @param br 错误结果
     * @author youli.chen
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getChildProductStockAjax", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getChildProductStockAjax(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getChildProductStock(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品有效期
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/product/getGuaranteeInfo", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getGuaranteeInfo(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getGuaranteeInfo(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品详情获取产品关联的合同
     *
     * @param detailTabDataGetDTO 入参
     * @param br 错误结果
     * @author youli.chen
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/product/getContract", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getContract(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), XbbRefTypeEnum.CONTRACT.getCode(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRelativeContract(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品采购合同
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/product/getPurchase", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchase(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.PURCHASE.getCode(), null, DistributorMarkEnum.OTHER.getCode());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPurchaseList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品入库记录
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/product/getInstock", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInstock(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getProductInstock(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品出库记录
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/product/getOutstock", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getOutstock(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getProductOutstock(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 产品批次信息
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/product/getBatchList", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getBatchList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getChildProductBatchList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 详情页跟进记录
     *
     * @param detailCommunicateDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-12 11:13
     */
    @RequestMapping(value = "/detailCommunicate/list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String customerCommunicateList(@RequestBody @Valid DetailCommunicateDTO detailCommunicateDTO, BindingResult br) {
        XbbResponse<DetailCommunicateVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), detailCommunicateDTO.getParentBusinessType(), null, detailCommunicateDTO.getDistributorMark());
                DetailCommunicateVO detailCommunicateVO = saasDetailTabService.customerCommunicateList(detailCommunicateDTO);
                response = new XbbResponse<>(detailCommunicateVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 客户上下级
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-15 14:12
     */
    @RequestMapping(value = "/parentAndChildCustomer/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getParentAndChildCustomer(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO parentAndChildCustomerGetVO = saasDetailTabService.getParentAndChildCustomer(detailTabDataGetDTO);
                response = new XbbResponse<>(parentAndChildCustomerGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }


    @RequestMapping(value = "/defaultBomVersion/set", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String setDefaultBomVersion(@RequestBody @Valid SetDefaultBomVersionDTO setDefaultBomVersionDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.BOM_BILL.getCode(), null, setDefaultBomVersionDTO.getDistributorMark());
                BaseVO baseVO = saasDetailTabService.setDefaultBomVersion(setDefaultBomVersionDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/linkAdd/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String linkAddGet(@RequestBody @Valid LinkAddGetDTO linkAddGetDTO, BindingResult br) {
        XbbResponse<FormDataAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(linkAddGetDTO.getSaasMark(), linkAddGetDTO.getLinkBusinessType(), null, linkAddGetDTO.getDistributorMark());
                FormDataAddGetVO formDataAddGetVO = saasDetailTabService.linkAddGet(linkAddGetDTO);
                response = new XbbResponse<>(formDataAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/clue/convert/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueConvertGet(@RequestBody @Valid DetailClueConvertDTO clueConvertDTO, BindingResult br) {
        XbbResponse<FormDataAddGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataAddGetVO formDataAddGetVO = saasDetailTabService.clueConvertGet(clueConvertDTO);
                response = new XbbResponse<>(formDataAddGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/clue/convert/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueConvertSave(@RequestBody @Valid ClueConvertSaveDTO clueConvertDTO, BindingResult br) {
        XbbResponse<ClueConvertSaveVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ClueConvertSaveVO clueConvertSaveVO = saasDetailTabService.clueConvertSave(clueConvertDTO);
                response = new XbbResponse<>(clueConvertSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取流失（输单）原因
     *
     * @param saasBaseDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-19 20:02
     */
    @RequestMapping(value = "/getWastageCase", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWastageCase(@RequestBody @Valid SaasBaseDTO saasBaseDTO, BindingResult br) {
        XbbResponse<DictionaryArrayVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DictionaryArrayVO dictionaryArrayVO = saasDetailTabService.getWastageCase(saasBaseDTO);
                response = new XbbResponse<>(dictionaryArrayVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 退货退款关联作废发票tab
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/refund/invoice/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefundInvoice(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefundInvoice(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 合同退货退款tab
     *
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/refund/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefund(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefund(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/product/getPurchaseReturned", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchaseReturned(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPurchaseReturnedList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }

        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/redInvoice/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRedInvoice(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(), null, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRedInvoice(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 获取待采购缺货对应的数据列表详情
     *
     * @param formDataGetDTO 列表筛选条件
     * @author youli.chen
     * @since V1.0
     * @return String
     * @date 2019/3/22 13:46
     */
    @RequestMapping(value = "/getPurchasedDetail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPurchasedDetail(@RequestBody @Valid FormDataGetDTO formDataGetDTO, BindingResult br) {
        XbbResponse<ListPurchasedVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ListPurchasedVO listPurchasedVO = saasDetailTabService.getPurchasedDetail(formDataGetDTO);
                response = new XbbResponse<>(listPurchasedVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/getNewPurchasedDetail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getNewPurchasedDetail(@RequestBody @Valid OrderOnPinDTO orderOnPinDTO, BindingResult br) {
        XbbResponse<WaitPurchaseProductVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                WaitPurchaseProductVO waitPurchaseProductVO = saasDetailTabService.getPurchasedProductDetail(orderOnPinDTO);
                response = new XbbResponse<>(waitPurchaseProductVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }
    /**
     * 获取待生产缺货对应的数据列表详情
     *
     * @param formDataGetDTO 列表筛选条件
     * @author youli.chen
     * @since V1.0
     * @return String
     * @date 2019/3/22 13:46
     */
    @RequestMapping(value = "/getProduceDetail", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getProduceDetail(@RequestBody @Valid FormDataGetDTO formDataGetDTO, BindingResult br) {
        XbbResponse<ListPurchasedVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ListPurchasedVO listPurchasedVO = saasDetailTabService.getProduceDetail(formDataGetDTO);
                response = new XbbResponse<>(listPurchasedVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * Description: 移动端历史版本（报价单）
     * @param quotationHistoryDTO
     * @param br
     * @author 刘阳
     * @date 2019/8/20 4:07 PM
     * @since v1.0
     */
    @RequestMapping(value = "/quotationHistory", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getHistory(@RequestBody @Valid QuotationHistoryDTO quotationHistoryDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = quotationService.getHistory(quotationHistoryDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * Description: 报价单
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @author 刘阳
     * @date 2019/8/28 2:21 PM
     * @since v1.0
     */
    @RequestMapping(value = "/quotationTabData/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getQuotationContract(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getQuotationTabData(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/copy", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String copy(@RequestBody @Valid DetailCopyDTO detailCopyDTO, BindingResult br) {
        XbbResponse<FormDataUpdateGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataUpdateGetVO formDataUpdateGetVO = saasDetailTabService.copy(detailCopyDTO);
                response = new XbbResponse<>(formDataUpdateGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/management/paymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getManagementPayment(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(detailTabDataGetDTO.getSaasMark(), detailTabDataGetDTO.getBusinessType(),0L, detailTabDataGetDTO.getDistributorMark());
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaymentSheetOnManagement(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取退货退款中的关联红冲回款单列表
     * @param detailTabDataGetDTO 入参
     * @param br 校验
     * @return 回参
     * @author zhouwq
     * @date 2019/12/2 18:50
     */
    @RequestMapping(value = "/refund/redPaymentSheet/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefundRedPaymentSheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefundRedPaymentSheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
    /**
     * 获取退货退款中的关联红冲应收款列表
     * @param detailTabDataGetDTO 入参
     * @param br 校验
     * @return java.lang.String
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/refund/redPayment/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRefundRedPayment(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getRefundRedPayment(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 详情页获取关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author chaoxiong.lei
     * @date 11:04 2019/3/18
     * @since v1.0
     **/
    @RequestMapping(value = "/relationProductList/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getRelationProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<RelationProductListVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                RelationProductListVO relationProductListVO = businessProductService.getRelationProductList(detailTabDataGetDTO);
                response = new XbbResponse<>(relationProductListVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 详情页汇总关联产品信息
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author feng.zheng
     * @date 2019-10-28 10:16
     **/
    @RequestMapping(value = "/productList/summary", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String summaryProductList(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductSummaryVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductSummaryVO productSummaryVO = businessProductService.summaryProductList(detailTabDataGetDTO);
                response = new XbbResponse<>(productSummaryVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * @Description:  产品详情页产品介绍tab接口
     * @Param: [detailTabDataGetDTO, br]
     * @return: java.lang.String
     * @Author: cyy
     * @Date: 2019/10/9
     */
    @RequestMapping(value = "/product/getInstruction", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getInstruction(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<ProductDetailVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ProductDetailVO productDetailVO = saasDetailTabService.getProductInstruction(detailTabDataGetDTO);
                response = new XbbResponse<>(productDetailVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 供应商详情页添加供货产品
     *
     * @param supplierProductAddDTO 入参
     * @param br 校验
     * @return 回参
     * @author jiantao.xiong
     * @date 2020/4/28
     */
    @RequestMapping(value = "/supplierProduct/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String addSupplierProduct(@RequestBody @Valid SupplierProductAddDTO supplierProductAddDTO, BindingResult br){
        XbbResponse<FormDataUpdateVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                FormDataUpdateVO formDataUpdateVO = saasDetailTabService.addSupplierProduct(supplierProductAddDTO);
                response = new XbbResponse<>(formDataUpdateVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }

        return JSON.toJSONString(response);
    }

    /**
     * 供应商详情页删除供货产品
     *
     * @param supplierProductDelDTO 入参
     * @param br 参数绑定校验
     * @return 回参
     * @author jiantao.xiong
     * @date 2020/4/28
     */
    @RequestMapping(value = "/supplierProduct/delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String delSupplierProduct(@RequestBody @Valid SupplierProductDelDTO supplierProductDelDTO, BindingResult br){
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.delSupplierProduct(supplierProductDelDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }

        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/supplierProduct/getLinkProductField", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getLinkProductField(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br){
        XbbResponse<SupplierProductVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                SupplierProductVO supplierProductVO = saasDetailTabService.getLinkProductField(detailTabDataGetDTO);
                response = new XbbResponse<>(supplierProductVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }

        return JSON.toJSONString(response);
    }

    /**
     * 费用
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/expenseTabData/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getExpenseTabData(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.detailExpenseList(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 移动端更新单据开启关闭状态
     * @param changeDocumentStatusSaveDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/changeDocumentStatus", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String changeDocumentStatus(@RequestBody @Valid ChangeDocumentStatusSaveDTO changeDocumentStatusSaveDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChangeDocumentStatusSaveVO changeDocumentStatusSaveVO = saasDetailTabService.changeDocumentStatus(changeDocumentStatusSaveDTO);
                response = new XbbResponse<>(changeDocumentStatusSaveVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取采购退货单中的关联红冲回款单列表
     * @param detailTabDataGetDTO 入参
     * @param br 校验
     * @return 回参
     * @author zhouwq
     * @date 2020/02/24 09:28
     */
    @PostMapping(value = "/returned/redPaySheet/get", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getReturnedRedPaySheet(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getReturnedRedPaySheet(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/returned/invoice/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getReturnedPurchaseInvoice(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getReturnedPurchaseInvoice(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/customerContract/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCustomerContract(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCustomerContract(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/purchaseOrder/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getContractPurchase(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getContractPurchase(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * @param changeClueStatusDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clue/invalid", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueInvalid(@RequestBody @Valid ChangeClueStatusDTO changeClueStatusDTO, BindingResult br) {
        XbbResponse<ChangeClueStatusVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChangeClueStatusVO changeClueStatusVO = clueService.invalidClue(changeClueStatusDTO);
                response = new XbbResponse<>(changeClueStatusVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * @param changeClueStatusDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/clue/follow", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String clueFollow(@RequestBody @Valid ChangeClueStatusDTO changeClueStatusDTO, BindingResult br) {
        XbbResponse<ChangeClueStatusVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ChangeClueStatusVO changeClueStatusVO = clueService.followClue(changeClueStatusDTO);
                response = new XbbResponse<>(changeClueStatusVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 固定额度记录
     * @param detailTabDataGetDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/creditFixedLimit/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCreditFixedLimit(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCreditFixedLimit(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/creditTemporaryLimit/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCreditTemporaryLimit(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCreditTemporaryLimit(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    @RequestMapping(value = "/creditCardBill/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getCreditCardBill(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getCreditCardBill(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 应收款
     *
     * @param detailTabDataGetDTO
     * @param br
     * @throws
     * @author long.rao
     * @date 2019-04-04 14:04
     *
     * @version2 这时候的老回款计划已经是应收款了 2020/9/1
     */
    @RequestMapping(value = "/paymentTask/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getPaymentTask(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getPaymentTask(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 关联新建之前需要做的一些事情
     *
     * @param linkAddBeforeDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/linkAdd/before", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String linkAddBefore(@RequestBody @Valid LinkAddBeforeDTO linkAddBeforeDTO, BindingResult br) {
        XbbResponse<DetailTabLinkAddBeforeVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                TransmittableThreadLocalUtil.setValue(linkAddBeforeDTO.getSaasMark(), linkAddBeforeDTO.getLinkBusinessType(), null, linkAddBeforeDTO.getDistributorMark());
                DetailTabLinkAddBeforeVO detailTabLinkAddBeforeVO = saasDetailTabService.linkAddBefore(linkAddBeforeDTO);
                response = new XbbResponse<>(detailTabLinkAddBeforeVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 经销商档案账号管理tab页
     * @param detailTabDataGetDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author xinpeng.jiang
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/distributor/account/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getDistributorAccount(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getDistributorAccount(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 普通发货
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/normalShipping/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getNormalShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<OutstockShippingVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                OutstockShippingVO outstockShippingVO = saasDetailTabService.normalShipping(outstockShippingDTO);
                response = new XbbResponse<>(outstockShippingVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 电子面单发货
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/electronicShipping/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getElectronicShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<OutstockShippingVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                OutstockShippingVO outstockShippingVO = saasDetailTabService.electronicShipping(outstockShippingDTO);
                response = new XbbResponse<>(outstockShippingVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 普通发货保存
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/normalShipping/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveNormalShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveNormalShipping(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 电子面单发货保存
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/electronicShipping/save", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveElectronicShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.saveElectronicShipping(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 获取物流信息
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/expressInfo/get", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getExpressInfo(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<OutstockShippingVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                OutstockShippingVO outstockShippingVO = saasDetailTabService.getExpressInfo(outstockShippingDTO);
                response = new XbbResponse<>(outstockShippingVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     * 电子面单复打
     * @param outstockShippingDTO
     * @param br
     * @return java.lang.String
     * @throws XbbException
     * @author lee
     * @date 2021/1/7 15:21
     * @version 1.0
     */
    @RequestMapping(value = "/electronicShipping/copy", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String copyElectronicShipping(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.copyElectronicShipping(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * @Author: wujian
     * @Description: 取消发货接口
     * @Date: 上午9:51 2021/2/2
     * @Param: [outstockShippingDTO, br]
     * @return: java.lang.String
     **/
    @RequestMapping(value = "/delivery/update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String updateExpress(@RequestBody @Valid OutstockShippingDTO outstockShippingDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = saasDetailTabService.cancelDelivery(outstockShippingDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 获取核销记录
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author jyh
     * @since v1.0
     **/
    @RequestMapping(value = "/writeOffRecord", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getWriteOffRecord(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.getWriteOffRecord(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }
    /**
     * 获取营销活动适用对象
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author jyh
     * @since v1.0
     **/
    @RequestMapping(value = "/marketing/applicableObjects", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String marketingApplicableObjects(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.marketingApplicableObjects(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }


    /**
     * 获取营销活动不适用商品
     *
     * @param detailTabDataGetDTO
     * @param br
     * @author jyh
     * @since v1.0
     **/
    @RequestMapping(value = "/marketing/inapplicableGoods", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String marketingInapplicableGoods(@RequestBody @Valid DetailTabDataGetDTO detailTabDataGetDTO, BindingResult br) {
        XbbResponse<DetailTabGetVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                DetailTabGetVO detailTabGetVO = saasDetailTabService.marketingInapplicableGoods(detailTabDataGetDTO);
                response = new XbbResponse<>(detailTabGetVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

    /**
     *
     * @Description: 获取审批记录
     * @param approvalRecordsDTO
     * @param br
     * @return: java.lang.String
     * @Author: shen.yang
     * @Date: 2022/6/14  17:24
    */
    @RequestMapping(value = "/approve/records", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String approveRecords(@RequestBody @Valid ApprovalRecordsDTO approvalRecordsDTO, BindingResult br) {
        XbbResponse<ApprovalRecordsVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                ApprovalRecordsVO approvalRecordsVO = saasDetailTabService.getApprovalRecords(approvalRecordsDTO);
                response = new XbbResponse<>(approvalRecordsVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

}
